home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / Toolbox / WDEFColorSample / WDEFColorSampleWDEF.c < prev   
Encoding:
C/C++ Source or Header  |  1994-12-09  |  24.4 KB  |  764 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.     This file contains the routines that show how to obtain the colors
  4.     needed to display system 7 windows.
  5.     
  6.     Please check the WDEF sample for details on how to write one.
  7. */
  8.  
  9.     
  10.     #include <Values.h>
  11.     #include <Types.h>
  12.     #include <Resources.h>
  13.     #include <QuickDraw.h>
  14.     #include <Fonts.h>
  15.     #include <Events.h>
  16.     #include <Windows.h>
  17.     #include <Menus.h>
  18.     #include <TextEdit.h>
  19.     #include <Dialogs.h>
  20.     #include <Desk.h>
  21.     
  22.     #include <ToolUtils.h>
  23.     #include <Memory.h>
  24.     #include <SegLoad.h>
  25.     #include <Files.h>
  26.     #include <OSUtils.h>
  27.     #include <OSEvents.h>
  28.     #include <DiskInit.h>
  29.     #include <Packages.h>
  30.     #include <Traps.h>
  31.     #include <Script.h>
  32.  
  33. #include "WDEFColorSample.h"        /* bring in all the #defines for WDEFSample */
  34.  
  35. #define minTitleH            19 /* minumum height without SICN */
  36. #define minTitleHIcon        21 /* minumum height with SICN */
  37.  
  38. #define wContentColor 0
  39. #define wFrameColor 1
  40. #define wHiliteLight 5        /* these are the part numbers for the sys 7 WCTB record */
  41. #define wTitleBarLight 7
  42. #define wTitleBarDark 8
  43. #define wTingeBarLight 11
  44. #define wTingeBarDark 12
  45.  
  46. struct WInfoRec {
  47.         short ascent;
  48.         short descent;
  49.         short height;
  50.         short delta;
  51.         };
  52. typedef struct WInfoRec WInfoRec;
  53.  
  54. /* use this struct to pass around the different state parameters. */
  55. struct     DataRecord {
  56.         Boolean gadgetHilite;
  57.         WindowPtr window;
  58.         Boolean isColor;
  59.         CTabHandle awCTable;
  60.         Boolean threeDWind;
  61.         WInfoRec WInfo;
  62.         };
  63.         
  64.  
  65. typedef struct DataRecord DataRecord;
  66. typedef DataRecord *DataRecordPtr;
  67. typedef DataRecord **DataRecordHandle;
  68.  
  69. Boolean CheckShades(short what, DataRecordHandle data);
  70. void SetUpRatioColor(short hilitePart, short percent, RGBColor *tempRGB, DataRecordHandle data);
  71. void SetUpColor(short part, RGBColor *rgb, DataRecordHandle data);
  72. //extern void MakeRatioRGB(RGBColor *start, RGBColor *end, RGBColor *dest, short percent);
  73. Boolean CheckCTab(short part, CTabHandle target, RGBColor *rgb);
  74. void FakeWDEF(WindowPtr window, Boolean hilite);
  75. void SetForeBackColors (RGBColor *fore, RGBColor *back,  DataRecordHandle data);
  76. void DrawTitleString(Rect tempRect, short *indentL, short *indentR, DataRecordHandle data);
  77.  
  78. pascal void DoDraw(short depth, short flags, GDHandle device, DataRecordHandle data);
  79. void CheckAvailableColors(short depth, GDHandle device, DataRecordHandle data);
  80. void BuildTitleRect(Rect *main, Rect *final, DataRecordHandle data);
  81. short CalculateTHeight( DataRecordHandle data);
  82.  
  83.  
  84. /* IMPORTANT: The window manager messes up with the current port and obtains
  85.    any results it wants; in this sample we take whatever port is the window,
  86.    so you better get the window with NewCWindow or GetNewCWindow for the color
  87.    cute stuff to work.
  88.    
  89.    The hilite parameter is used to display the goaway and zoom boxes in their
  90.    un/hilited states.
  91.    
  92.    This sample draws the standard window with title bar; nothing else!
  93.    
  94.    Note that although this code mimics the WDEF it is not one, make sure you
  95.    check the WDEF sample before attempting to write your own.
  96. */
  97.  
  98.  
  99. /* === A C version of the MakeRatioRGB, in case you're compiling for PowerPC. === */
  100.  
  101. void MakeRatioRGB(RGBColor *start, RGBColor *end, RGBColor *dest, short percent)
  102. {
  103.     enum {            kMultVal = 0x1111 };
  104.     unsigned short    multValue;
  105.     short            counter, *destPtr;
  106.     short            blendValue, darkValue, lightValue;
  107.     Boolean            flipIt;
  108.  
  109.     multValue = (unsigned short)(kMultVal * percent);
  110.     
  111.     for (counter = 0; counter < 3; counter ++) {
  112.         darkValue = ((short *)end)[counter];    // get the proper colors for
  113.         lightValue = ((short *)start)[counter];    // this time through the loop
  114.  
  115.         flipIt = ((unsigned long)lightValue > (unsigned long)darkValue);
  116.  
  117.         blendValue = darkValue - lightValue;
  118.  
  119.         if (flipIt == true)                        // flip if subtraction would overflow
  120.             blendValue = -blendValue;            
  121.  
  122.         blendValue = ((unsigned short)blendValue * multValue) >> 16;
  123.                                                 // quick multiply and shift
  124.  
  125.         if (flipIt == true)                        // flip it back if it's flipped
  126.             blendValue = -blendValue;            
  127.  
  128.         destPtr = &(((short *)dest)[counter]);    // get pointer to the right location
  129.                                                 // in dest RGB record
  130.         *destPtr = blendValue + lightValue;        // fill it in with right color
  131.     }
  132.  
  133. }
  134.  
  135.  
  136. /* Shows how to blend the colors in the 'wctb' to obtain the system 7 look]
  137.    for windows.
  138. */
  139.  
  140. void FakeWDEF(WindowPtr window, Boolean hilite)
  141. {
  142. DataRecordHandle dataHandle;
  143. AuxWinHandle auxWind;
  144. RGBColor fore, back;
  145. short fontID;
  146.  
  147.     fontID = window->txFont;
  148.     
  149.     TextFont(GetSysFont());
  150.     dataHandle = (DataRecordHandle)NewHandle(sizeof(DataRecord));
  151.     
  152.     if ((((CGrafPtr)window)->portVersion) && 0xC000) {
  153.       (*dataHandle) -> isColor = true;
  154.       GetAuxWin(window, &(auxWind));
  155.       (*dataHandle) ->awCTable = (*auxWind)->awCTable;
  156.       GetForeColor(&fore);
  157.       GetBackColor(&back);
  158.     }
  159.     else {
  160.       (*dataHandle) -> isColor = false;
  161.     }
  162.     (*dataHandle) -> window = window;
  163.     (*dataHandle) -> gadgetHilite = hilite;
  164.     
  165.     PenNormal();
  166.     
  167.     /* the main routine calls device loop passing the address of the routine
  168.        that does the actual drawing.
  169.     */
  170.     /* see IM VI for details on DeviceLoop */
  171.     DeviceLoop(window->visRgn, (DeviceLoopDrawingProcPtr)DoDraw, (long)dataHandle, 0);
  172.     
  173.     /**** Unlock and dispose of stuff ****/
  174.     SetForeBackColors(&fore, &back, dataHandle);
  175.  
  176.     TextFont(fontID);
  177.     
  178.     DisposeHandle((Handle) dataHandle);
  179.  
  180. }
  181.  
  182. void DrawTitleString(Rect tempRect, short *indentL, short *indentR, DataRecordHandle data)
  183. {
  184. RGBColor foreColor, backColor;
  185. RgnHandle tempRgn;
  186. short slop;
  187.  
  188.     tempRgn = NewRgn();
  189.  
  190.     if ( ((WindowPeek)((*data) -> window))-> hilited ) { /* window is hilited */
  191.       SetUpColor(wFrameColor, &foreColor, data);
  192.       SetUpRatioColor(wTitleBarLight, 0x1, &backColor, data); /* back color is a shade */
  193.     }
  194.     else {    /* unhilited requires a shade for fore color */
  195.       SetUpRatioColor(wHiliteLight, 0xA, &foreColor, data);
  196.       SetUpColor(wContentColor, &backColor, data);
  197.     }
  198.  
  199.     SetForeBackColors(&foreColor, &backColor, data);
  200.     FrameRect(&tempRect);
  201.     
  202.     InsetRect(&tempRect, 1, 1);
  203.     EraseRect(&tempRect);
  204.     
  205.     if ( ((WindowPeek)((*data) -> window))-> hilited && (*data) -> threeDWind ) { /* window is hilited draw tinges */
  206.     /* the colors in the title bar are combinations of colors taken from
  207.        discontiguous parts; so first we get the two colors
  208.        and then we mix them directly.
  209.     */
  210.  
  211.       SetUpColor(wTingeBarLight, &foreColor, data);
  212.       SetUpColor(wTitleBarDark, &backColor, data);
  213.       MakeRatioRGB(&foreColor, &backColor, &foreColor, 0x0);
  214.       SetForeBackColors(&foreColor, 0L, data); /* set fore color */
  215.       
  216.       MoveTo(tempRect.left, tempRect.bottom-1);
  217.       Line(0, -(tempRect.bottom-tempRect.top-1));
  218.       Line(tempRect.right-tempRect.left-1,0);
  219.  
  220.       SetUpRatioColor(wTingeBarLight, 0x4, &foreColor, data);
  221.       SetForeBackColors(&foreColor, 0L, data); /* set fore color */
  222.  
  223.       Line(0, tempRect.bottom-tempRect.top-1);
  224.       Line(-(tempRect.right-tempRect.left-1), 0);
  225.     }
  226.     
  227.     *indentL = (tempRect.right-tempRect.left-((WindowPeek)((*data) -> window))-> titleWidth) >> 1;
  228.     
  229.     slop = 2; /* minimum distance from edge */
  230.     if ( ((WindowPeek)((*data) -> window))-> goAwayFlag ) slop = 32; /* make room for box */
  231.     
  232.     if ( *indentL < slop ) *indentL = slop;  /* normalize it if needed */
  233.     *indentR = *indentL;    /* we'll need this for right side of title bar */
  234.  
  235.     slop = 2; /* minimum distance from edge */
  236.  
  237.     if ( ((WindowPeek)((*data) -> window))-> spareFlag ) slop = 32; /* make room for box */
  238.     
  239.     if ( *indentR < slop ) *indentR = slop;  /* normalize it if needed */
  240.     
  241.     *indentL += tempRect.left; /* this puts us at the beginning of the title string */
  242.  
  243.     MoveTo(*indentL, tempRect.top + (*data)->WInfo.ascent + 1);
  244.     
  245.  /* we want to clip the right edge in case the title is too long */    
  246.     GetClip(tempRgn);
  247.  
  248.     tempRect.right -= *indentR;
  249.     ClipRect(&tempRect);
  250.     SectRgn(tempRgn, (((*data) -> window))->clipRgn, (((*data) -> window))->clipRgn);
  251.     
  252.     if ( ((WindowPeek)((*data) -> window))-> hilited ) { /* window is hilited */
  253.       SetUpColor(wTextColor, &foreColor, data);
  254.     }
  255.     else {    /* unhilited requires a shade for fore color */
  256.       SetUpRatioColor(wHiliteLight, 0x7, &foreColor, data);
  257.     }
  258.  
  259.     SetUpRatioColor(wTitleBarLight, 0x1, &backColor, data); /* back color is a shade */
  260.     SetForeBackColors(&foreColor, &backColor, data);
  261.     TextMode(srcOr);
  262.     HLock(((WindowPeek)((*data) -> window))-> titleHandle);
  263.     DrawString(*(((WindowPeek)((*data) -> window))-> titleHandle));
  264.     HUnlock(((WindowPeek)((*data) -> window))-> titleHandle);
  265.     
  266.     SetClip(tempRgn); /* restore clip */
  267.     DisposeRgn(tempRgn);
  268. }
  269.  
  270. void DrawStripes(Rect tempRect, short indentL, short indentR, DataRecordHandle data)
  271. {
  272. RGBColor foreColor;
  273. Rect saveRect = tempRect;
  274. short hilitePattern[] = {0xFF00, 0xFF00, 0xFF00, 0xFF00};
  275.  
  276.       SetUpRatioColor(wHiliteLight, 0x8, &foreColor, data);
  277.       SetForeBackColors(&foreColor, 0L, data);
  278.  
  279.  
  280.       tempRect.right = indentL;    /* where the title string begins */
  281.       if (((WindowPeek)((*data) -> window))-> titleWidth ) 
  282.           tempRect.right -= 6 ; /* a little bit to the left is there is a title */
  283.     
  284.     SetZone(SystemZone());
  285.     
  286.     FillRect(&tempRect,(ConstPatternParam) hilitePattern);
  287.     
  288.     tempRect = saveRect;        /* start again for right half */
  289.  
  290.  
  291.     tempRect.left =  tempRect.right - indentR; /* at the end of string */
  292.     
  293.     if (((WindowPeek)((*data) -> window))-> titleWidth ) 
  294.       tempRect.left += 6;        /* make a litle room for title */
  295.     
  296.     FillRect(&tempRect,(ConstPatternParam) hilitePattern);
  297.     
  298. }
  299.  
  300. /* draws the go away box if any */
  301. void DrawGoAwayBox(Rect tempRect, DataRecordHandle data)
  302. {
  303. RGBColor foreColor, backColor;
  304. CTabHandle ct;    /* needed for colorization to work */
  305.  
  306. /* the WDEF carries these pixmaps as resources carrying the pieces; this
  307.    is what the currently used stuff looks like.
  308. */
  309. /* for a WDEF you may want to store the data in a more convenient place */
  310.  
  311. /* go away box pixel data unhilited */
  312. const short pixelsUn[] = {0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,
  313.                     0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,
  314.                     0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,
  315.                     0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA};
  316.                     
  317. /* go away box pixel data hilited */
  318. const short pixelsHi[] = {0xFFFF,0xFFFF,0xFFF0,
  319.                     0xF555,0x5F55,0x5500,
  320.                     0xF5F5,0x5F55,0xF500,
  321.                     0xF55F,0x5F5F,0x5500,
  322.                     0xF555,0x5555,0x5500,
  323.                     0xFFFF,0x555F,0xFF00,
  324.                     0xF555,0x5555,0x5500,
  325.                     0xF55F,0x5F5F,0x5500,
  326.                     0xF5F5,0x5F55,0xF500,
  327.                     0xF555,0x5F55,0x5500,
  328.                     0xF000,0x0000,0x0000};
  329.  
  330. const Rect pixMapBoundsRect = {0, 0, 0xB, 0xB};
  331.  
  332.  
  333. /* go away box pixel data unhilited */
  334. short bitsUn[] = {0xFFE0,0x8020,0x8020,0x8020,0x8020,0x8020,0x8020,0x8020,0x8020,0x8020,0xFFE0};
  335. /* go away box pixel data unhilited */
  336. short bitsHi[] = {0xFFE0,0x8420,0xA4A0,0x9520,0x8020,0xF1E0,0x8020,0x9520,0xA4A0,0x8420,0xFFE0};
  337.  
  338. /* used when shades are available */
  339. PixMap pmUn =   {pixelsUn, 0x8006, 
  340.                 {0, 0, 0xB, 0xB},
  341.                 0,0,0,0x00480000, 0x00480000, 0, 4,1,4, 0, 0L, 0};
  342. PixMap pmHi =   {pixelsHi, 0x8006, 
  343.                 {0, 0, 0xB, 0xB},
  344.                 0,0,0,0x00480000, 0x00480000, 0, 4,1,4, 0, 0L, 0};
  345.  
  346. /* used when colored windows are not possible */
  347. BitMap bwBmUn = {bitsUn, 2, pixMapBoundsRect};
  348. BitMap bwBmHi = {bitsHi, 2, pixMapBoundsRect};
  349. BitMapPtr bmPtr;
  350.  
  351.  
  352.  
  353.     ct = (CTabHandle)NewHandleClear(16);
  354.     
  355.     pmUn.pmTable = pmHi.pmTable = ct;
  356.     
  357.     tempRect.left +=6;
  358.     tempRect.right = tempRect.left+13;
  359.     tempRect.bottom = tempRect.top+11;
  360.     
  361.     SetUpRatioColor(wTitleBarLight, 0x1, &backColor, data); /* back color is a shade */
  362.     SetForeBackColors(0L, &backColor, data);
  363.  
  364.     EraseRect(&tempRect); /* erase to title bar back color */
  365.     
  366.     InsetRect(&tempRect, 1, 0);
  367.     
  368.     if ( ! (*data)->threeDWind ) {  /* do black and white */
  369.       if (  (*data) -> gadgetHilite )  /* draw it is hilited */
  370.         bmPtr = &bwBmHi;
  371.       else
  372.         bmPtr = &bwBmUn;
  373.     }
  374.     else {/* colored calls are ok */
  375.       if (  (*data) -> gadgetHilite ) { /* draw it is hilited */
  376.         SetUpColor(wTitleBarDark, &foreColor, data);
  377.         SetUpColor(wTingeBarLight, &backColor, data); /* back color is a shade */
  378.         bmPtr = (BitMap *)(&pmHi);
  379.       }
  380.       else {    /* unhilited requires a shade for fore color */
  381.         SetUpColor(wTitleBarDark, &backColor, data);
  382.         SetUpColor(wTitleBarLight, &foreColor, data); /* back color is a shade */
  383.          bmPtr =  (BitMap *)(&pmUn);
  384.       }
  385.     
  386.       SetForeBackColors(&foreColor, &backColor, data);
  387.     }
  388.     CopyBits(bmPtr,&( ((*data)->window)->portBits),&(bmPtr->bounds),&tempRect,srcCopy, 0L);
  389.  
  390.     if ( (*data)->threeDWind  &&  ! (*data)->gadgetHilite ) {  /* tinge only when colors are available */
  391.       SetUpColor(wTitleBarLight, &foreColor, data); /* back color is a shade */
  392.       SetUpColor(wTingeBarDark, &backColor, data);
  393.       MakeRatioRGB(&foreColor, &backColor, &foreColor, 0xF);
  394.       SetForeBackColors(&foreColor, 0L, data);
  395.       FrameRect(&tempRect);
  396.       MoveTo(tempRect.left+2, tempRect.bottom-2);
  397.       LineTo(tempRect.right-2, tempRect.bottom-2);
  398.       LineTo(tempRect.right-2, tempRect.top+2);
  399.  
  400.       tempRect.top +=1;
  401.       tempRect.left += 1;
  402.       SetUpRatioColor(wTingeBarLight, 0x0, &foreColor, data); /* back color is a shade */
  403.       SetForeBackColors(&foreColor, 0L, data);
  404.       FrameRect(&tempRect);
  405.     }
  406.     DisposeHandle((Handle) ct);
  407. }
  408.  
  409. /* draws the zoom box if any */
  410. void DrawZoomBox(Rect tempRect, DataRecordHandle data)
  411. {
  412. RGBColor foreColor, backColor;
  413. CTabHandle ct;    /* needed for colorization to work */
  414.  
  415. /* the WDEF carries these pixmaps as resources carrying the pieces; this
  416.    is what the currently used stuff looks like.
  417.    You may want to stuff it in a more convenient place.
  418. */
  419. /* go zoom box pixel data unhilited */
  420. const short pixelsUn[] = {0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,
  421.                     0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,
  422.                     0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,
  423.                     0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA,0xAAAA};
  424.                     
  425. /* go zoom box pixel data hilited */
  426. const short pixelsHi[] = {0xFFFF,0xFFFF,0xFFF0,
  427.                     0xF555,0x5F55,0x5500,
  428.                     0xF5F5,0x5F55,0xF500,
  429.                     0xF55F,0x5F5F,0x5500,
  430.                     0xF555,0x5555,0x5500,
  431.                     0xFFFF,0x555F,0xFF00,
  432.                     0xF555,0x5555,0x5500,
  433.                     0xF55F,0x5F5F,0x5500,
  434.                     0xF5F5,0x5F55,0xF500,
  435.                     0xF555,0x5F55,0x5500,
  436.                     0xF000,0x0000,0x0000};
  437.  
  438. /* for b/w: bitmap pixels, un/hilited */            
  439. const short bitsUn[] = {0xFFE0,0x8220,0x8220,0x8220,0x8220,0x8220,0xFE20,0x8020,0x8020,0x8020,0xFFE0};
  440. const short bitsHi[] = {0xFFE0,0x8420,0xA4A0,0x9520,0x8020,0xF1E0,0x8020,0x9520,0xA4A0,0x8420,0xFFE0};
  441.  
  442. /* used when shades are available */
  443. PixMap pmUn =   {pixelsUn, 0x8006, 
  444.                 {0,0,0xB, 0xB},
  445.                 0,0,0,0x00480000, 0x00480000, 0, 4,1,4, 0, 0L, 0};
  446. PixMap pmHi =   {pixelsHi, 0x8006, 
  447.                 {0,0,0xB, 0xB},
  448.                 0,0,0,0x00480000, 0x00480000, 0, 4,1,4, 0, 0L, 0};
  449.  
  450. /* used when colored windows are not possible */
  451. BitMap bwBmUn = {bitsUn, 2, {0, 0, 0xB, 0xB};
  452. BitMap bwBmHi = {bitsHi, 2, {0, 0, 0xB, 0xB};
  453.  
  454. BitMapPtr bmPtr;
  455.  
  456.     ct = (CTabHandle)NewHandleClear(16);
  457.     
  458.     pmUn.pmTable = pmHi.pmTable = ct;
  459.     
  460.     tempRect.right -=6;
  461.     tempRect.left = tempRect.right-13;
  462.     tempRect.bottom = tempRect.top+11;
  463.     
  464.     SetUpRatioColor(wTitleBarLight, 0x1, &backColor, data); /* back color is a shade */
  465.     SetForeBackColors(0L, &backColor, data);
  466.  
  467.     EraseRect(&tempRect); /* erase to title bar back color */
  468.     
  469.     InsetRect(&tempRect, 1, 0);
  470.     
  471.     if ( ! (*data)->threeDWind ) {  /* do black and white */
  472.       if (  (*data) -> gadgetHilite )  /* draw it is hilited */
  473.         bmPtr = &bwBmHi;
  474.       else
  475.         bmPtr = &bwBmUn;
  476.     }
  477.     else {/* colored calls are ok */
  478.       if (  (*data) -> gadgetHilite ) { /* draw it is hilited */
  479.         SetUpColor(wTitleBarDark, &foreColor, data);
  480.         SetUpColor(wTingeBarLight, &backColor, data); /* back color is a shade */
  481.         bmPtr = (BitMap *)(&pmHi);
  482.       }
  483.       else {    /* unhilited requires a shade for fore color */
  484.         SetUpColor(wTitleBarDark, &backColor, data);
  485.         SetUpColor(wTitleBarLight, &foreColor, data); /* back color is a shade */
  486.          bmPtr =  (BitMap *)(&pmUn);
  487.       }
  488.     
  489.       SetForeBackColors(&foreColor, &backColor, data);
  490.     }
  491.     CopyBits(bmPtr,&( ((*data)->window)->portBits),&(bmPtr->bounds),&tempRect,srcCopy, 0L);
  492.  
  493.     if ( (*data)->threeDWind  &&  ! (*data)->gadgetHilite ) {  /* tinge only when colors are available */
  494.       SetUpColor(wTitleBarLight, &foreColor, data); /* back color is a shade */
  495.       SetUpColor(wTingeBarDark, &backColor, data);
  496.       MakeRatioRGB(&foreColor, &backColor, &foreColor, 0xF);
  497.       SetForeBackColors(&foreColor, 0L, data);
  498.       FrameRect(&tempRect);
  499.       MoveTo(tempRect.left+2, tempRect.bottom-2);
  500.       LineTo(tempRect.right-2, tempRect.bottom-2);
  501.       LineTo(tempRect.right-2, tempRect.top+2);
  502.  
  503.       MoveTo(tempRect.left+2, tempRect.bottom-5);
  504.       LineTo(tempRect.right-5, tempRect.bottom-5);
  505.       LineTo(tempRect.right-5, tempRect.top+2);
  506.  
  507.       tempRect.top +=1;
  508.       tempRect.left += 1;
  509.       SetUpRatioColor(wTingeBarLight, 0x0, &foreColor, data); /* back color is a shade */
  510.       SetForeBackColors(&foreColor, 0L, data);
  511.       FrameRect(&tempRect);
  512.     }
  513.     DisposeHandle((Handle) ct);
  514. }
  515.  
  516. /* this routine is called for each device intersected by the call to DeviceLoop; 
  517.    QuickDraw sets the device and calls this routine.
  518. */
  519. pascal void DoDraw(short depth, short flags,GDHandle device, DataRecordHandle data)
  520. {
  521. #pragma unused (flags)
  522.  
  523. RGBColor foreColor, backColor;
  524. Rect    mainRect, tempRect;
  525. short indentL, indentR;
  526. THz saveZone;    
  527.  
  528.     saveZone = GetZone();
  529.     
  530.     CheckAvailableColors(depth, device, data);
  531.  
  532.     if ( ((WindowPeek)((*data) -> window))-> hilited ) /* window is hilited */
  533.       SetUpColor(wFrameColor, &foreColor, data);
  534.     else {    /* unhilited requires a shade get it first */
  535.       SetUpRatioColor(wHiliteLight, 0xA, &foreColor, data);
  536.     }
  537.     
  538.     SetUpColor(wContentColor, &backColor, data);
  539.     
  540.     SetForeBackColors(&foreColor, &backColor, data);
  541.     
  542.     mainRect = ((*data)->window)->portRect;
  543.     InsetRect(&mainRect, 10,10);    /* make the fake window smaller than the port rect so we can see it well */
  544.  
  545.     FrameRect(&mainRect);        /* frame the body */
  546.     
  547.     /* shadow drawing would go here */
  548.     
  549.     BuildTitleRect(&mainRect, &tempRect, data);
  550.  
  551.     DrawTitleString(tempRect, &indentL, &indentR, data);
  552.     
  553.     InsetRect(&tempRect, 1, 1); /* make it smaller */
  554.     
  555.     
  556.     /* all this stuff (title bar pattern, and gadgets are drawn only if window is hilited */
  557.     if ( ((WindowPeek)((*data) -> window))-> hilited ) { /* window is hilited */
  558.       InsetRect(&tempRect, 1, (*data)->WInfo.delta);
  559.       mainRect = tempRect;                                /* save  */
  560.       
  561.       DrawStripes(tempRect, indentL, indentR, data);
  562.  
  563.       if ( ((WindowPeek)((*data) -> window))-> goAwayFlag )
  564.         DrawGoAwayBox(tempRect, data); 
  565.  
  566.       if ( ((WindowPeek)((*data) -> window))-> spareFlag ) /* if we have a zoom box */
  567.         DrawZoomBox(tempRect, data); 
  568.  
  569.     }
  570.     SetZone(saveZone);    /* just in case */
  571.     
  572. }
  573.  
  574. short CalculateTHeight( DataRecordHandle data)
  575. {
  576. short result, temp;
  577.  
  578.     GetFontInfo((FontInfo *)&((*data)->WInfo));
  579.     result = ((*data)->WInfo.ascent + (*data)->WInfo.descent + 4) | 0x1; /* height odd for symmetry ???? */
  580.     if ( result < minTitleH ) { /* need to enforce a minimun height */
  581.       temp = (minTitleH - result) >> 1; /* how much more small is it */
  582.       (*data)->WInfo.ascent += temp;    /* make ascent a the minimum */
  583.       result = minTitleH;
  584.     }
  585.     (*data)->WInfo.height = result;
  586.     (*data)->WInfo.delta = (result - 13) >> 1;
  587.     
  588.     return result;
  589. }
  590. void BuildTitleRect(Rect *main, Rect *final, DataRecordHandle data)
  591. {
  592.     final->top = main->top;
  593.     final->bottom = main->top + CalculateTHeight(data);
  594.     final->left = main->left;
  595.     final->right = main->right -1;
  596. };
  597.  
  598. /* gets and set the fore/background colors for an operation and sets them in.
  599.    My theory is that if SetUpColor has to return black and white for all shades
  600.    then the boolean for color windows is off at the time we get here; so we use
  601.    it to decide what call to make to set the colors.
  602. */
  603. void SetForeBackColors (RGBColor *fore, RGBColor *back,  DataRecordHandle data)
  604. {
  605.     if ( (*data)->threeDWind ) { /* colored calls are ok */
  606.       if (fore) RGBForeColor(fore);
  607.       if (back) RGBBackColor(back);
  608.     }
  609.     else { /* need to use old style calls ************* */
  610.       if (fore) ForeColor( *((long *)fore));
  611.       if (back) BackColor(*((long *)back));
  612.     }
  613. }
  614.  
  615. /* This proc makes sure the shades (colors) needed to draw the new style
  616.    window are present; if not the window is drawn using black and white.
  617.    The 'result' of the search is put in (*data)->threeDWind; if true then
  618.    color drawing is possible.
  619. */
  620. void CheckAvailableColors(short depth, GDHandle device, DataRecordHandle data)
  621. {
  622. GDHandle saveDevice;
  623. Boolean result = false;
  624.  
  625.     saveDevice = GetGDevice();
  626.     SetGDevice(device);
  627.     (*data)->threeDWind = true; /* prime it */
  628.     if (depth >= 2) {
  629.       if ( result = CheckShades(wHiliteLight, data) ) { 
  630.         if ( result = CheckShades(wTitleBarLight, data) ) {
  631.           result = CheckShades(wTingeBarLight, data); /* we found all the shades, maybe */
  632.         }
  633.       }
  634.     }
  635.     SetGDevice(saveDevice);
  636.     (*data)->threeDWind = result;
  637. }
  638.  
  639. /* this routine checks if the colors needed are present; if colors are
  640.    available it returns true otherwise it returns false.
  641.    we differ from the WDEF in the sense that the tinge shades are 
  642.    tingeLight, titleBarDark, 0
  643.    tingeLight, tingeDark,     4
  644.    titleBarLight, tingeDark, F
  645.    
  646.    but in the following code we treat them as percentages of
  647.    tingeLight + tingeDark
  648.    
  649.    Note that the routines where the correct shades are needed do
  650.    use the exact combination of colors (and percentage.)
  651. */
  652. Boolean CheckShades(short what, DataRecordHandle data)
  653. {
  654. long newIndex, oldIndex = 'csd ';    /* a weird index value to start with */
  655. char percent[11] =    {0x0, 0x7, 0x8, 0xA, 0xD,    /* window highlite shade percentage */
  656.                      0x0, 0x1, 0x4,                /* wTitleBar shade percentage        */
  657.                      0x0, 0x4, 0xF};            /* Tinge shade percentages            */
  658. RGBColor tempColor;
  659. Boolean result = true;    /* optimist */
  660. short start, next, i;
  661.  
  662.     switch (what) {
  663.             case wHiliteLight:
  664.               start = 0;
  665.               next = 5;
  666.               break;
  667.             case wTitleBarLight:
  668.               start = 5;
  669.               next = 8;
  670.               break;
  671.             case wTingeBarLight: 
  672.             /* tinge shades should be treated differently but this is a good approximation */
  673.               start = 8;
  674.               next = 11;
  675.               break;
  676.               }
  677.     for (i=start; i< next; i++) {
  678.       SetUpRatioColor(what, percent[i], &tempColor, data);
  679.       newIndex = Color2Index(&tempColor);    /* get corresponding index */
  680.       if (newIndex != oldIndex ) { /* got a different color for all shades */
  681.         oldIndex = newIndex; /* prime index for next round */
  682.       }
  683.       else {
  684.         result = false;
  685.         goto bail;
  686.       }
  687.     }
  688. bail:
  689.     return result;
  690. }
  691.  
  692. /* this procedure returns the color in between two other colors modulo percent */
  693. void SetUpRatioColor(short hilitePart, short percent, RGBColor *tempRGB, DataRecordHandle data)
  694. {
  695. RGBColor startRGB, endRGB;
  696.  
  697.     SetUpColor(hilitePart, &startRGB, data);        /* parts come in pairs; once we have the light    */
  698.     SetUpColor(hilitePart+1, &endRGB, data);        /* color the dark follows.                        */
  699.     MakeRatioRGB(&startRGB, &endRGB, tempRGB, percent);/* now find the in between color.                */
  700. }
  701.  
  702. /* takes a part number and returns the RGB color associated with it.
  703.    This proc ALWAYS returns a color.
  704. */
  705. void SetUpColor(short part, RGBColor *rgb, DataRecordHandle data)
  706. {
  707. CTabHandle auxCTable;
  708. RGBColor defaultThreeDColors[] = {{0xFFFF, 0xFFFF, 0xFFFF},        /* wContentColor                 */
  709.                                   {0x0000, 0x0000, 0x0000},        /* wFrameColor                     */
  710.                                   {0x0000, 0x0000, 0x0000},        /* wTextColor                     */
  711.                                   {0x0000, 0x0000, 0x0000},        /* wHiliteColor (not used)         */
  712.                                  
  713.                                   {0xFFFF, 0xFFFF, 0xFFFF},        /* wTitleBarColor (not used)     */
  714.                                   {0xFFFF, 0xFFFF, 0xFFFF},        /* wHiliteLight                 */
  715.                                   {0x0000, 0x0000, 0x0000},        /* wHiliteDark                     */
  716.                                   {0xFFFF, 0xFFFF, 0xFFFF},        /* wTitleBarLight                 */
  717.                                   
  718.                                   {0x0000, 0x0000, 0x0000},        /* wTitleBarDark                 */
  719.                                   {0xCCCC, 0xCCCC, 0xFFFF},        /* wDialogLight                 */
  720.                                   {0x0000, 0x0000, 0x0000},        /* wDialogDark                     */
  721.                                   {0xCCCC, 0xCCCC, 0xFFFF},        /* wTingeLight                     */
  722.                                   {0x3333, 0x3333, 0x6666}};    /* wTingeLight                     */
  723.                                   
  724. char bwColors[] = {0xFF, 0x0, 0x0, 0x0, 
  725.                    0xFF, 0x0, 0x0, 0xFF, 
  726.                    0xFF, 0x0, 0x0, 0x0, 0x0};
  727.  
  728.     if ( (*data)->threeDWind ) { /* color can be used */
  729.       if ( ! CheckCTab(part, (*data)->awCTable, rgb ) ) { /* true means we are done */
  730.         if ( auxCTable = (CTabHandle)GetResource('wctb', 0) ) {/* the auxWind CTable is not good try loading wctb */
  731.           if ( CheckCTab(part, auxCTable, rgb ) ) { 
  732.             return;
  733.           }
  734.         }
  735.         *rgb = defaultThreeDColors[part];    /* can not find colors, pass default ones */
  736.       }
  737.     }
  738.     else { /* use black and white */
  739.       if (part > 12 ) DebugStr("\weird part in bw search");
  740.       else
  741.           if ( bwColors[part] ) (*(long *)rgb) = whiteColor;
  742.         else (*(long *)rgb) = blackColor;
  743.     }
  744. }
  745.  
  746. /* Checks if the part number is in the window color table, if it is returns true
  747.    and passes back the color. If not found it returns false and the color
  748.    remains undefined.
  749. */
  750. Boolean CheckCTab(short part, CTabHandle target, RGBColor *rgb)
  751. {
  752. short i;
  753. Boolean result = false;
  754.  
  755.     for (i = 0; i <= (*target)->ctSize; i++) {
  756.       if ( (*target)->ctTable[i].value == part ) {
  757.         result = true;
  758.         *rgb = (*target)->ctTable[i].rgb;
  759.         break;
  760.       }
  761.     }
  762.     return result;
  763. }
  764.